import {
	bdDJ,
	changeOrg,
	downLoadFile,
	getOrderDetailByBillNo,
	getOrderList,
	uploadFile,
} from '@/api/user';
const wx = uni;
export class Utils {
	static acctId = '6825cde47c35d8';
	// static userName = 'demo';
	static passWord = '78451200';
	static userName = 'demo';

	/**
	 * 获取表单id
	 * @param value 名称
	 * @returns 表单id
	 */
	static getFormId(value : string) {
		if (!value) return;
		let formId = '';
		switch (value) {
			case '入库单':
				formId = 'k21eb489422264033b6bbdbc0184d115b';
				break;
			case '出库单':
				formId = 'k6527695463a648c3a99a3a455da889d9';
				break;
			case '调拨单':
				formId = 'STK_TransferDirect';
				break;
			case '员工':
				formId = 'BD_Empinfo';
				break;
			case '客户':
				formId = 'BD_Customer';
				break;
			case '仓库':
				formId = 'BD_STOCK';
				break;
			case '物料':
				formId = 'BD_MATERIAL';
				break;
			case '费用项目':
				formId = 'BD_Expense';
				break;
			case '辅助资料':
				formId = 'BOS_ASSISTANTDATA_DETAIL';
				break;
			case '组织机构':
				formId = 'ORG_Organizations';
				break;
			case '供应商':
				formId = 'BD_Supplier';
				break;
			case '部门':
				formId = 'BD_Department';
				break;
			case '员工任岗':
				formId = 'BD_NEWSTAFF';
				break;
			case '费用项目':
				formId = 'BD_Expense';
				break;
			case '组织机构':
				formId = 'ORG_Organizations';
				break;
			case '费用价目表':
				formId = 'kc6f60b2a9f24458ba614493d821eb8e3';
				break;
			case '批号':
				formId = 'BD_BatchMainFile';
				break;
			case '即时库存':
				formId = 'STK_Inventory';
				break;
		}
		return formId;
	}
	/**
	 * 通过条件查询数据
	 */
	static async getListByFilterValue(FormId : string, filterKey : string, filterValue : string, FieldKeys : string = '', compare : string = 'Like') {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId,
				FieldKeys: FieldKeys || 'FNumber,FName,FDocumentStatus,FForbidStatus',
				FilterString: [
					Utils.getFilterString(filterKey, filterValue, compare, '', ''),
					Utils.getFilterString('FDocumentStatus', 'C', '105', '', ''),
					Utils.getFilterString('FForbidStatus', 'A', '105', '', ''),
				],
				OrderString: '',
			}),
		})
		return res;
	}

	/**
	 * 获取过滤字符串
	 * @param key 字段名
	 * @param value 值
	 * @param compare 比较方式
	 * @returns 过滤字符串
	 */
	static getFilterString(
		key : string,
		value : string | number | boolean,
		compare : string,
		left : string = '(',
		right : string = ')',
		logic : string = '0'
	) {
		let obj = {
			FieldName: key,
			Compare: compare,
			Value: value,
			Left: left,
			Right: right,
			Logic: logic,
		};

		return obj;
	}
	// 通过修理状态获取中文
	static getRepairState(state : string) {
		let text = '';
		if (state === 'A') {
			// text = '修理中';
		} else if (state === 'B') {
			text = '已报废';
		} else if (state === 'C') {
			text = '修理完成';
		}
		return text;
	}
	static limitDecimals(num : number, decimalPlaces = 4) {
		if (typeof num === 'number') {
			const factor = Math.pow(10, decimalPlaces);
			return Math.floor(num * factor) / factor;
		}
		return num;
	}
	// 切换组织
	static async selectData  (v : any) {
		if (v && v.FName) {
			// 调用切换组织api
			const res:any =  await changeOrg({
				data:JSON.stringify({
				OrgNumber:v.FNumber
				})
			})
			const isOk = Utils.isReqOk(res)
			console.log(isOk);
			const newOrg = {
				FNumber: v.FNumber,
				FName: v.FName
			}
			Utils.setStorage("currentOrganization", newOrg )
			return newOrg
		}
		return false
		
	}
	/**
	 * 四舍五入处理数字
	 * @param num 需要处理的数字
	 * @param decimalPlaces 保留小数位数，默认为4位
	 * @returns 处理后的数字
	 */
	static roundNumber(num : number, decimalPlaces = 4) {
		if (typeof num === 'number') {
			const factor = Math.pow(10, decimalPlaces);
			return Math.round(num * factor) / factor;
		}
		return num;
	}

	/**
	 * 节流方法
	 * @param func
	 * @param delay
	 * @returns
	 */
	static throttle<T extends (...args : any[]) => any>(
		func : T,
		delay : number
	) : (...args : Parameters<T>) => void {
		let timer : NodeJS.Timeout | null = null;
		return function (this : ThisParameterType<T>, ...args : Parameters<T>) {
			if (!timer) {
				func.apply(this, args);
				timer = setTimeout(() => {
					timer = null;
				}, delay);
			}
		};
	}

	/**
	 * 报错模态弹窗
	 * @param text 提示信息
	 * @param fn 回调
	 */
	static showErr(text ?: string, fn ?: Function) {
		uni.showModal({
			title: '提示',
			content: text || '出错了，请稍后重试！',
			showCancel: false,
			confirmColor: '#3974f6',
			success: () => {
				fn && fn();
			},
		});
	}
	static showModal(text : string, fn ?: Function) {
		uni.showModal({
			title: '提示',
			content: text,
			success(res) {
				if (res.confirm) {
					fn && fn();
				} else if (res.cancel) {
					console.log('用户点击取消');
				}
			},
		});
	}
	/**
	 * 提示弹窗
	 * @param err
	 */
	static showToast(err ?: string) {
		uni.showToast({
			title: err || '出错了！',
			icon: 'none',
			duration: 2000,
		});
	}
	/**
	 * 微信扫码
	 */
	static scanCode(fn : Function, onlyFromCamera = true) {
		uni.scanCode({
			// 是否只能拍照
			onlyFromCamera,
			complete(res) {
				// console.log(res);
				if (!res || res.errMsg != 'scanCode:ok')
					return Utils.showErr('获取二维码数据失败');
				// 扫码获取的数据
				const code = res.result;
				fn(res, code)

			},
		});
	}
	/** 获取单据类型 */
	static getServiceType() {
		/** 单据类型 */
		return [
			{
				title: '入库单',
				iconImg: '/static/my/pay.png',
				FormId: Utils.getFormId("入库单"),
				FieldKeys: '',
				pageUrl: 'rkd',
				number: 0,
			},
			{
				title: '出库单',
				iconImg: '/static/my/wait.png',
				FormId: Utils.getFormId("出库单"),
				FieldKeys: '',
				pageUrl: 'ckd',
				number: 0,
			},
			{
				title: '调拨单',
				iconImg: '/static/my/ywc.png',
				FormId: Utils.getFormId("调拨单"),
				FieldKeys: '',
				pageUrl: 'dbd',
				number: 0,
			},
		];
	}
	// 通过title获取其中一项
	static getOneServiceType(title : string) {
		const serviceType = this.getServiceType();
		return serviceType.find((item) => item.title === title);
	}
	/**
	 * 通过批号和物料编码获取即时库存信息
	 * @param materialCode 物料
	 * @param lot 批号
	 * @returns 布尔值，true有库存
	 */
	static async getMaterialIInventoryByMaterialCodeAndLot(
		materialCode : string,
		lot : string,
		showLoad = true
	) {
		const res : any = await getOrderList(
			{
				data: JSON.stringify({
					FormId: Utils.getFormId('即时库存'),
					FieldKeys:
						'FLot.FNumber,FMaterialId.FNumber,FExpiryDate,FProduceDate,FBaseQty',
					FilterString: [
						Utils.getFilterString('FMaterialId.FNumber', materialCode, '=', '', ''),
						Utils.getFilterString(
							'FLot.FNumber',
							lot,
							'=',
							'',
							''
						),
						Utils.getFilterString(
							'FBaseQty',
							0,
							'>',
							'',
							''
						),
					
					],
					OrderString: '',
				}),
			},
			showLoad
		);
		console.log('库存信息', res);
		return res.length > 0 ? res : false;
	}
	/**
	 * 获取登录类型
	 */
	static getLoginType() {
		return Utils.getStorage('loginType') || ''
	}
	/**
	 * 获取客户信息
	 */
	static getCustomerInfo() {
		return Utils.getStorage('currentCustomer') || {}
	}
	/**
	 * 获取客户手机号
	 */
	static getCustomerPhone() {
		return Utils.getStorage('userPhone')?.data?.phone_info?.purePhoneNumber || ''
	}
	/**
	 * 缓存数据
	 */
	static setStorage(key : any, value : any) {
		uni.setStorageSync(key, value);
	}
	/**
	 * 获取缓存数据
	 */
	static getStorage(key : any) {
		return wx.getStorageSync(key);
	}
	/**
	 * 删除缓存数据
	 */
	static removeStorage(key : any) {
		return wx.removeStorageSync(key);
	}
	/**
	 * 时间戳转换时间格式
	 * @param timestamp
	 * @returns
	 */
	static formatTimestamp(timestamp : number) {
		const date = new Date(Number(timestamp));
		const year = date.getFullYear();
		const month = String(date.getMonth() + 1).padStart(2, '0');
		const day = String(date.getDate()).padStart(2, '0');
		const hours = String(date.getHours()).padStart(2, '0');
		const minutes = String(date.getMinutes()).padStart(2, '0');
		// const seconds = String(date.getSeconds()).padStart(2, '0');

		return `${year}-${month}-${day} ${hours}:${minutes}`;
	}
	/**
	 * 时间戳转换日期
	 * @param timestamp
	 * @returns
	 */
	static formatDate(timestamp : number) {
		const date = new Date(Number(timestamp));
		const year = date.getFullYear();
		const month = String(date.getMonth() + 1).padStart(2, '0');
		const day = String(date.getDate()).padStart(2, '0');
		return `${year}-${month}-${day}`;
	}
	/**
	 * 获取派工状态
	 * @param state
	 * @returns
	 */
	static getCombo(state : string) {
		let text = '';
		if (state === 'A') {
			text = '已上料';
		} else if (state === 'B') {
			text = '已产出';
		}
		return text;
	}
	/**
	 * 获取模具属性
	 * @param state
	 * @returns
	 */
	static getMJAttr(state : string) {
		let text = '';
		if (state === 'S') {
			text = '单';
		} else if (state === 'M') {
			text = '混';
		}
		return text;
	}
	/**
	 * 获取派工单
	 * @param state
	 * @returns
	 */
	static getDispatchWork = async (FilterString : any) => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('派工单'),
				// 单据编号，生产订单号，派工状态，订单状态
				FieldKeys:
					'FBillNo,F_WALA_PRDCode,F_WALA_Combo1,FDocumentStatus,F_WALA_Combo,F_WALA_DMaterialName,F_WALA_DMaterialCode',
				FilterString,
				OrderString: '',
				TopRowCount: 300,
			}),
		});
		if (res.length === 0) {
			Utils.showToast('没有满足条件的单据');
			return [];
		}
		// 去掉多余的数据
		let list = res.filter((item : any) => {
			return item[0] != ' ' && item[1] != ' ';
		});

		list = list.map((item : any) => {
			let obj = {
				FBillNo: item[0],
				FName: item[1],
				// text: item[1] + '(' + item[0] + ')',
				F_WALA_PRDCode: item[1],
				F_WALA_Combo1: item[2],
				F_WALA_DMaterialCode: item[5],
				F_WALA_DMaterialName: item[5],
			};
			return obj;
		});

		// 去重
		return [...new Set(list)];
	};

	/**
	 * 获取该生产订单下得所有产出单
	 */
	static getInstrument = async (index : number, searchText : string) => {
		const FilterString = [
			Utils.getFilterString('FDocumentStatus', 'C', '=', '', ''),
			Utils.getFilterString('FNumber', searchText, 'Like', '(', '', '1'),
			Utils.getFilterString('FName', searchText, 'Like', '', ')'),
		];
		let FieldKeys = [
			'FNumber',
			'FName',
			'F_MonthlyReading',
			'F_InstrumentType.FNumber',
			'F_Range',
			'F_Magnification',
		];
		// 单元
		if (index == 0) {
			FieldKeys = [
				...FieldKeys,
				'F_VJKU_Base_iyi.FNumber',
				'F_VJKU_Base_187.FNumber',
				'F_VJKU_Base_kjx.FNumber',
				'F_BelongUnit.FNumber',
			];
		} else {
			// 公共
			FieldKeys = [
				...FieldKeys,
				'F_Project.FNumber',
				'F_Building.FNumber',
				'F_FLOOR.FNumber',
			];
		}

		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId(index == 0 ? '单元仪表' : '公共仪表'),
				// 单元读值、仪表类型、量程、倍率
				FieldKeys: FieldKeys.join(),
				FilterString,
				OrderString: '',
			}),
		});
		let list = res.map((item : any) => {
			let obj = {
				FBillNo: item[0],
				FName: item[1],
				F_MonthlyReading: item[2],
				type: index == 0 ? '单元仪表' : '公共仪表',
				F_InstrumentType: item[3],
				F_Range: item[4],
				F_Magnification: item[5],
				project: item[6],
				building: item[7],
				floor: item[8],
				unit: item[9],
			};
			return obj;
		});
		// 去重
		return list;
	};
	/**
	 * 获取员工
	 */
	static getEmployee = async (text : any) => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('员工'),
				FieldKeys: 'FNumber,FName,FUseOrgId,FForbidStatus,FDocumentStatus',
				FilterString: [
					Utils.getFilterString('FName', text, 'Like', '', ''),
					// Utils.getFilterString('FUseOrgId', 1, 'Like', '', ''),
					Utils.getFilterString('FForbidStatus', 'A', '=', '', ''),
					Utils.getFilterString('FDocumentStatus', 'C', '=', '', ''),
				],
				OrderString: '',
			}),
		});

		let list = res.map((item : any) => {
			let obj = {
				FBillNo: item[0],
				FName: item[1],
				text: item[1],
			};
			return obj;
		});
		// 去重
		return [...new Set(list)];
	};
	// 获取用户列表
	static getUserList = async (text : any) => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: 'BOS_User',
				FieldKeys: 'FName,FForbidStatus',
				FilterString: [
					Utils.getFilterString('FName', text, 'Like', '', ''),
					Utils.getFilterString('FForbidStatus', 'A', '=', '', ''),
				],
				OrderString: '',
			}),
		});

		let list = res.map((item : any) => {
			let obj = {
				// FBillNo: item[0],
				FName: item[0],
				text: item[0],
			};
			return obj;
		});
		// 去重
		return [...new Set(list)];
	};
	// 获取模架
	static getMold = async (text : any) => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('模具资料'),
				FieldKeys: 'FNumber,FName',
				FilterString: [Utils.getFilterString('FName', text, 'Like', '', '')],
				OrderString: '',
			}),
		});

		let list = res.map((item : any) => {
			let obj = {
				FBillNo: item[0],
				FName: item[1],
				text: item[1],
				// F_WALA_MoldCode: item[3],
			};
			return obj;
		});
		// 去重

		return [...new Set(list)];
	};
	// 获取所有的木模号
	static getAllMoldCode = async () => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('模具资料'),
				FieldKeys: 'F_WALA_MoldCode',
				FilterString: [],
				OrderString: '',
			}),
		});

		let list = res.map((item : any) => {
			let obj = {
				FBillNo: item[0],
				text: item[0],
			};
			return obj;
		});
		// 判断数据一样的去重
		return this.uniqueList(list, 'FBillNo');
	};
	/**
	 * 列表数据去重
	 */
	static uniqueList = (list : any, key : string = 'FBillNo') => {
		// 判断某个字段相同然后去重
		let newList = list.filter((item : any, index : number) => {
			return list.findIndex((item2 : any) => item2[key] === item[key]) === index;
		});
		return newList;
	};
	/**
	 * 获取模号
	 * @param text
	 * @returns
	 */
	static getMoldCode = async (text : any) => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('模具资料'),
				FieldKeys: 'F_WALA_MoldCode,F_WALA_Cavity,F_WALA_MoldCombo',
				FilterString: [
					Utils.getFilterString('F_WALA_MoldCode', text, 'Like', '', ''),
				],
				OrderString: '',
			}),
		});

		let list = res.map((item : any) => {
			let obj = {
				FBillNo: item[0],
				FName: item[0],
				F_WALA_Cavity: item[1],
				F_WALA_MoldCombo: item[2],
				text: item[0],
			};
			return obj;
		});
		// 去重

		return [...new Set(list)];
	};
	/**
	 * 获取工作资源（机台）
	 */
	static getWorkResource = async (text : string, filterIndex : number = 0) => {
		const FilterString = [
			Utils.getFilterString('F_WALA_type', '机台', '=', '', ''),
		];
		if (filterIndex == 1) {
			FilterString.push(Utils.getFilterString('FNumber', text, 'Like', '', ''));
		} else {
			FilterString.push(Utils.getFilterString('FName', text, 'Like', '', ''));
		}
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('工作资源'),
				FieldKeys: 'FNumber,FName,F_WALA_type',
				FilterString,
				OrderString: '',
			}),
		});

		let list = res.map((item : any) => {
			let obj = {
				FBillNo: item[0],
				FName: item[1],
				text: item[1] + '(' + item[0] + ')',
			};
			return obj;
		});
		// 去重
		return [...new Set(list)];
	};
	/**
	 * 通过物料名称列表获取物料编码列表
	 */
	static getMaterialCodeByName = async (arr : any) => {
		let FilterString = [] as any;
		arr.forEach((item : any) => {
			FilterString.push(
				Utils.getFilterString('FName', item, '67', '', '', '1')
			);
		});

		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('物料单'),
				FieldKeys: 'FNumber,FName',
				FilterString,
				OrderString: '',
			}),
		});

		let list = res.map((item : any) => {
			let obj = {
				FBillNo: item[0],
				FName: item[1],
				text: item[1],
			};
			return obj;
		});
		// 去重
		return list;
	};

	// 获取物料
	static getMaterialCode = async (
		text : string,
		filterIndex : number = 0,
		FBaseProperty ?: string,
		FBaseProperty2 ?: string,
		FilterStringList : any = []
	) => {
		const FilterString = [];
		if (filterIndex == 0) {
			FilterString.push(Utils.getFilterString('FName', text, 'Like', '', ''));
		} else {
			FilterString.push(Utils.getFilterString('FNumber', text, 'Like', '', ''));
		}
		if (FBaseProperty) {
			if (FBaseProperty2) {
				FilterString.push(
					Utils.getFilterString(
						'FBaseProperty',
						FBaseProperty,
						'60',
						'(',
						'',
						'1'
					)
				);
				FilterString.push(
					Utils.getFilterString(
						'FBaseProperty',
						FBaseProperty2,
						'60',
						'',
						')',
						''
					)
				);
			} else {
				FilterString.push(
					Utils.getFilterString(
						'FBaseProperty',
						FBaseProperty,
						'60',
						'',
						'',
						''
					)
				);
			}
		} else {
			// FilterString.push(
			//   Utils.getFilterString('FBaseProperty', '02.02', '60', '', '', '')
			// );
			// FilterString.push(
			//   Utils.getFilterString('FBaseProperty', '02.03', '60', '', '', '0')
			// );
		}

		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('物料单'),
				FieldKeys: 'FNumber,FName,FUseOrgId,FBaseProperty,FSpecification',
				FilterString: [...FilterString, ...FilterStringList],
				OrderString: '',
				TopRowCount: 300,
			}),
		});

		let list = res.map((item : any) => {
			let obj = {
				FBillNo: item[0],
				FName: item[1],
				text: item[1],
				FSpecification: item[4],
			};
			return obj;
		});
		// 去重
		return [...new Set(list)];
	};
	/**
	 * 通过物料id获取物料详情信息
	 */
	static getMaterialInfoById = async (Id : number) => {
		const res : any = await getOrderDetailByBillNo({
			FormId: Utils.getFormId('物料单'),
			data: JSON.stringify({
				Id: Id,
			}),
		});
		if (res.Result.ResponseStatus.IsSuccess) {
			return res.Result.Result;
		}
		return {};
	};
	/**
	 * 原料数量计算逻辑
	 * @param data 物料信息
	 * @param qty 成品数量
	 * @returns
	 */
	static calculateLogic = (data : any, qty : number) => {
		// 计算用料比例
		const ratio =
			data.BaseNumerator && data.BaseDenominator
				? data.BaseNumerator / data.BaseDenominator
				: data.F_WALA_materialsUsedRatio;
		// 计算基本数量
		let count = Number(qty) * ratio;
		const gd = data.FFIXSCRAPQTY || data.FFixScrapQty;
		// 判断是否有固定损耗
		if (gd) {
			count = Number(gd) + count;
		}
		const scrapRate = data.FSCRAPRATE || data.FScrapRate;
		// 变动损耗
		if (scrapRate && scrapRate > 0) {
			count = count * (1 + Number(scrapRate) / 100);
		}
		return Utils.limitDecimals(count || 0);
	};
	/**
	 * 获取水口类型的拌料单
	 */
	static getNozzleTypeBlD = async (ProductionOrder : string, number : number) => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('拌料单'),
				FieldKeys:
					'FBillNo,F_XLSX_ProductionOrder,FDocumentStatus,F_WALA_BillTypeID,F_WALA_materialCodeColor,F_WALA_MixBalance',
				FilterString: [
					Utils.getFilterString('F_XLSX_ProductionOrder', ProductionOrder, '='),
					Utils.getFilterString('F_WALA_materialCodeColor', number, '='),
					Utils.getFilterString(
						'F_WALA_BillTypeID',
						Utils.getBLDTypeIdByType(),
						'='
					),
					Utils.getFilterString('F_WALA_MixBalance', 0, '>'),
					Utils.getFilterString('FDocumentStatus', 'C', '='),
				],
				OrderString: '',
			}),
		});
		// 等待所有请求结束
		const list = await Promise.all(
			res.map(async (item : any) => {
				return await this.getBlDByBillNo(item[0]);
			})
		);
		let arr = [] as any;
		let obj = [
			{
				F_WALA_MixBalance: 0,
				FEntity: [] as any,
			},
		] as any;
		console.log(list, '-----');

		list.forEach((item : any, i : number) => {
			// 判断obj是否已经存在 F_WALA_NozzleMaterialCode一样的数据
			const index = obj.findIndex(
				(o : any) =>
					o.F_WALA_NozzleMaterialCode === item.F_WALA_materialCodeColor.Number
			);
			// 如果存在就把数量相加
			if (index != -1) {
				return {
					...obj[index],
					F_WALA_MixBalance:
						obj[index].F_WALA_MixBalance + item.F_WALA_MixBalance,
				};
			}
			// 如果不存在就添加到obj中
			obj[i].F_WALA_MixBalance = item.F_WALA_MixBalance;
			obj[i].F_WALA_NozzleMaterialCode = item.F_WALA_materialCodeColor.Number;
			if (item.FEntity && item.FEntity.length > 0) {
				item.FEntity.forEach((v : any) => {
					const d = {
						F_WALA_NozzleMaterialCode: item.F_WALA_materialCodeColor.Number,
						F_WALA_MaterialCode: v.F_XLSX_MaterialCodeSubkey.Number,
						F_WALA_BaseProperty2: v.F_XLSX_MaterialCodeSubkey.Name[0].Value,
						F_WALA_Qty: v.F_XLSX_BalanceQuantity || v.F_XLSX_QuantitySubkey,
						F_WALA_QuantityConsumed: v.F_XLSX_QuantityConsumed,
						F_WALA_BalanceQuantity: v.F_XLSX_BalanceQuantity,
						F_WALA_materialsUsedRatio: v.F_WALA_materialsUsedRatio,
						max_count: v.F_XLSX_BalanceQuantity,
					};
					arr.push(d);
					obj[i].FEntity.push(d);
				});
			}
		});
		return obj;
	};
	/**
	 * 获取生成订单关联的所有拌料单，并计算上料数量
	 */
	static getBlDByProductionOrder = async (ProductionOrder : string) => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('拌料单'),
				FieldKeys:
					'FBillNo,F_XLSX_ProductionOrder,FDocumentStatus,F_WALA_BillTypeID',
				FilterString: [
					Utils.getFilterString('F_XLSX_ProductionOrder', ProductionOrder, '='),
					Utils.getFilterString('FDocumentStatus', 'C', '='),
				],
				OrderString: '',
			}),
		});
		// 等待所有请求结束
		const list = await Promise.all(
			res.map(async (item : any) => {
				return await this.getBlDByBillNo(item[0]);
			})
		);
		console.log(list, '获取关联的拌料单');

		// 数据合并，并把F_WALA_LoadingBalance 、F_WALA_MixBalance 相加
		let count = 0;
		let count2 = 0;
		let FEntity : any = [],
			F_WALA_NozzleDetail = [] as any;
		list.forEach((item : any) => {
			count += Number(item.F_WALA_LoadingBalance || 0);
			count2 += Number(item.F_WALA_MixBalance || 0);

			if (item.FEntity) FEntity.push(...item.FEntity);
			if (item.F_WALA_NozzleDetail)
				F_WALA_NozzleDetail.push(...item.F_WALA_NozzleDetail);
		});
		// FEntity 去掉编码一样的数据并把数量合并
		FEntity = FEntity.reduce((acc : any, curr : any) => {
			const index = acc.findIndex(
				(item : any) =>
					item.F_XLSX_MaterialCodeSubkey_Id ===
					curr.F_XLSX_MaterialCodeSubkey_Id
			);
			if (index !== -1) {
				acc[index].F_XLSX_BalanceQuantity += Number(
					curr.F_XLSX_BalanceQuantity
				);
				acc[index].F_XLSX_MaterialScale = acc[index].F_WALA_materialsUsedRatio;
			} else {
				acc.push({
					...curr,
					F_XLSX_MaterialScale: curr.F_WALA_materialsUsedRatio || 0,
					FScrapRate: curr.FScrapRate || 0,
					FFixScrapQty: curr.FFixScrapQty || 0,
				});
			}
			return acc;
		}, []);
		F_WALA_NozzleDetail = F_WALA_NozzleDetail.map((item : any) => {
			return {
				F_WALA_Base: item.F_WALA_NozzleMaterialCode.Number,
				F_WALA_Base1: item.F_WALA_MaterialCode.Number,
				F_WALA_BaseProperty: item.F_WALA_MaterialCode.Name[0].Value,
				F_WALA_Qty: item.F_WALA_Qty,
			};
		});
		return {
			// 上料结余
			F_WALA_LoadingBalance: Utils.limitDecimals(count),
			// 拌料结余
			F_WALA_MixBalance: Utils.limitDecimals(count2),
			// 原料明细
			FEntity,
			// 水口明细
			F_WALA_NozzleDetail,
		};
	};
	static getBlDByBillNo = async (Number : string) => {
		const res : any = await getOrderDetailByBillNo({
			FormId: Utils.getFormId('拌料单'),
			data: JSON.stringify({
				Number,
			}),
		});
		if (res.Result.ResponseStatus.IsSuccess) {
			return res.Result.Result;
		}
		return {};
	};
	/**
	 * 获取系统参数
	 */
	static getSystemParameter = async () => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('系统参数'),
				FieldKeys: 'FIsMContainReplace',
				FilterString: [],
				OrderString: '',
			}),
		});
		console.log(res, '获取系统参数');
	};
	/**
	 * 获取所有拌料单上料结余和拌料结余
	 */
	static getAllBlDBalanceQty = async (
		F_XLSX_ProductionOrder : string,
		F_WALA_materialCodeColor ?: string
	) => {
		const FilterString = [
			Utils.getFilterString(
				'F_XLSX_ProductionOrder',
				F_XLSX_ProductionOrder,
				'='
			),
			Utils.getFilterString('FDocumentStatus', 'C', '='),
			// Utils.getFilterString('F_WALA_MixBalance', '>', '='),
		];
		if (F_WALA_materialCodeColor) {
			FilterString.push(
				Utils.getFilterString(
					'F_WALA_materialCodeColor',
					F_WALA_materialCodeColor,
					'='
				)
			);
		}
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('拌料单'),
				FieldKeys:
					'FBillNo,F_XLSX_ProductionOrder,FDocumentStatus,F_WALA_MixBalance,c,F_WALA_materialCodeColor',
				FilterString,
				OrderString: '',
			}),
		});
		console.log(res, '获取所有拌料单上料结余和拌料结余');

		let MixBalance = 0,
			LoadingBalance = 0;
		if (res) {
			res.forEach((item : any) => {
				MixBalance += Number(item[3] || 0);
				LoadingBalance += Number(item[4] || 0);
			});
		}
		return {
			F_WALA_materialCodeColor: F_WALA_materialCodeColor || '',
			F_WALA_MixBalance: Utils.limitDecimals(MixBalance),
			F_WALA_LoadingBalance: Utils.limitDecimals(LoadingBalance),
		};
	};
	/**
	 * 获取版色料原料数量
	 */
	static getColorMaterialQty = async (number : string) => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('拌料单'),
				FieldKeys:
					'FBillNo,F_XLSX_ProductionOrder,FDocumentStatus,F_XLSX_MaterialCodeSubkey,F_XLSX_QuantitySubkey ',
				FilterString: [
					Utils.getFilterString('F_XLSX_MaterialCodeSubkey', number, '='),
					Utils.getFilterString('FDocumentStatus', 'C', '='),
					// Utils.getFilterString('F_WALA_MixBalance', '>', '='),
				],
				OrderString: '',
			}),
		});
		console.log(res, '获取版色料原料数量');
		let count = 0;
		res.forEach((item : any) => {
			count += item[4];
		});
		return {
			number,
			F_XLSX_QuantitySubkey: count,
		};
	};

	/**
	 * 获取所有的产出送检单
	 * @param isGoodProduct 是否良品 1是 0不是
	 * @returns
	 */
	static getAllCCSJ = async (
		searchText : string = '',
		isGoodProduct ?: number
	) => {
		console.log('获取产出送检单');

		let FilterString = [];
		if (isGoodProduct === 0) {
			FilterString.push(
				Utils.getFilterString('F_WALA_GoodProduct', false, '=')
			);
		} else if (isGoodProduct === 1) {
			FilterString.push(Utils.getFilterString('F_WALA_GoodProduct', true, '='));
		}

		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('产出送检单'),
				FieldKeys:
					'FBillNo,F_XLSX_ProductionOrder,F_WALA_GoodProduct,F_WALA_OutputQuantity',
				FilterString: [
					...FilterString,
					Utils.getFilterString('FDocumentStatus', 'C', '=', '', ''),
					Utils.getFilterString(
						'F_XLSX_ProductionOrder',
						searchText,
						'Like',
						'',
						''
					),
				],
				OrderString: '',
				TopRowCount: 300,
			}),
		});

		let list = res.map((item : any) => {
			let obj = {
				FBillNo: item[0],
				FName: item[1],
				text: item[1],
				F_WALA_OutputQuantity: item[3],
			};
			return obj;
		});
		// 去重

		let newList = list.reduce((acc : any, curr : any) => {
			const existingItem = acc.find((item : any) => item.text == curr.text);

			if (existingItem) {
				existingItem.F_WALA_OutputQuantity += curr.F_WALA_OutputQuantity;
			} else {
				acc.push(curr);
			}

			return acc;
		}, []);
		return newList;
		// return this.uniqueList(list, 'text');
	};
	static getXLList = async (searchText : string = '', isSK ?: number) => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('下料单'),
				FieldKeys:
					'F_XLSX_ProductionOrder,F_WALA_CuttingQuantity,F_WALA_IsWaterInlet',
				FilterString: [
					Utils.getFilterString('F_WALA_IsWaterInlet', true, '='),
					Utils.getFilterString('F_XLSX_ProductionOrder', searchText, 'Like'),
					Utils.getFilterString('FDocumentStatus', 'C', '='),
				],
				OrderString: '',
			}),
		});

		let list = res.map((item : any) => {
			let obj = {
				FBillNo: item[0],
				FName: item[0],
				text: item[0],
				F_WALA_OutputQuantity: item[1],
			};
			return obj;
		});
		// 去重

		let newList = list.reduce((acc : any, curr : any) => {
			const existingItem = acc.find((item : any) => item.text == curr.text);

			if (existingItem) {
				existingItem.F_WALA_OutputQuantity += curr.F_WALA_OutputQuantity;
			} else {
				acc.push(curr);
			}

			return acc;
		}, []);
		return newList;
	};
	/**
	 * 附件上传（绑定单据）
	 */
	static uploadFile = async (
		FileName : string,
		FormId : string,
		IsLast : boolean = true,
		InterId : string,
		BillNO : string,
		SendByte : string
	) => {
		const res = await uploadFile({
			data: JSON.stringify({
				FileName,
				FormId,
				IsLast,
				InterId,
				BillNO,
				SendByte,
			}),
		});
	};
	/**
	 * 下载附件
	 * @param FileId
	 * @returns
	 */
	static downLoadFile = async (FileId : string) => {
		const res : any = await downLoadFile({
			data: JSON.stringify({
				FileId,
			}),
		});
		if (res.Result.ResponseStatus.IsSuccess) {
			// console.log(res.Result, '请求成功');
			const data = res.Result;
			const type = this.getLastElement(data.FileName);
			return {
				base64: 'data:image/' + type + ';base64,' + data.FilePart,
				...data,
			};
		}
	};
	/**
	 * 获取图片类型
	 * @param str
	 * @returns
	 */
	static getLastElement = (str : string) => {
		if (typeof str !== 'string') {
			return ''; // 处理非字符串输入
		}

		const parts = str.split('.');
		return parts.length > 0 ? parts[parts.length - 1] : '';
	};
	/**
	 * 基于时间戳和随机数生成
	 */
	static generateUniqueString = () => {
		const timestamp = Date.now().toString(36); // 转换为36进制
		const random = Math.random().toString(36).substr(2, 9); // 取9位随机字符
		return `${timestamp}-${random}`;
	};
	/**
	 * 拍照 
	 */
	static selectFile = async (fn : Function, count : number = 1) => {
		wx.chooseMedia({
			count,
			mediaType: ['image'],
			sourceType: ['camera'],
			maxDuration: 30,
			camera: 'back',
			sizeType: ['compressed'],
			success(res) {
				// console.log(res.tempFiles[0].tempFilePath)
				// console.log(res.tempFiles[0].size)
				fn(res);
			},
		});
	};
	/**
	 * 预览图片
	 * @param url 图片连接
	 */
	static previewImageBase64 = (base64Url : any) => {
		wx.previewImage({
			current: base64Url, // 当前显示的图片 URL（必填）
			urls: [base64Url], // 预览的图片列表（数组，可包含多个 URL）
			success: function (res) {
				console.log('预览成功');
			},
			fail: function (err) {
				console.error('预览失败：', err);
			},
		});
	};
	// 获取base64图片类型
	static getImageTypeByHeader = (pureBase64 : any) => {
		if (!pureBase64 || typeof pureBase64 !== 'string') {
			console.error('输入不是有效的字符串');
			return null;
		}

		try {
			// 移除可能残留的前缀（如果有），确保处理的是纯 Base64
			const cleanBase64 = pureBase64.replace(/^data:image\/\w+;base64,/i, '');

			// 截取前 16 个字符解码（足够判断文件头）
			const base64Prefix = cleanBase64.substring(0, 16);
			const binary = atob(base64Prefix);

			// 将二进制字符串转为 Uint8Array 便于判断文件头
			const bytes = new Uint8Array(binary.length);
			for (let i = 0; i < binary.length; i++) {
				bytes[i] = binary.charCodeAt(i);
			}

			// 识别图片类型（根据文件头签名）
			let type = null;
			if (bytes.length >= 8 &&
				bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4E && bytes[3] === 0x47 &&
				bytes[4] === 0x0D && bytes[5] === 0x0A && bytes[6] === 0x1A && bytes[7] === 0x0A) {
				type = 'png';
			} else if (bytes.length >= 3 && bytes[0] === 0xFF && bytes[1] === 0xD8 && bytes[2] === 0xFF) {
				type = 'jpeg';
			} else if (bytes.length >= 6) {
				const isGif87 = bytes[0] === 0x47 && bytes[1] === 0x49 && bytes[2] === 0x46 &&
					bytes[3] === 0x38 && bytes[4] === 0x37 && bytes[5] === 0x61;
				const isGif89 = bytes[0] === 0x47 && bytes[1] === 0x49 && bytes[2] === 0x46 &&
					bytes[3] === 0x38 && bytes[4] === 0x39 && bytes[5] === 0x61;
				if (isGif87 || isGif89) type = 'gif';
			} else if (bytes.length >= 2 && bytes[0] === 0x42 && bytes[1] === 0x4D) {
				type = 'bmp';
			} else if (bytes.length >= 12 &&
				bytes[8] === 0x57 && bytes[9] === 0x45 && bytes[10] === 0x42 && bytes[11] === 0x50) {
				// WebP 签名（前4字节为RIFF，后4字节为文件大小，第8-11字节为"WEBP"）
				type = 'webp';
			}

			if (type) {
				// 拼接完整的 Base64 格式（带前缀）
				return `data:image/${type};base64,${cleanBase64}`;
			} else {
				console.warn('无法识别的图片类型');
				return null;
			}
		} catch (e) {
			console.error('处理 Base64 失败：', e);
			return null;
		}
	}
	/**
	 * 将 Base64 字符串按 30KB 分割为数组
	 * @param {string} base64Str 完整的 Base64 字符串（可带前缀，自动处理）
	 * @param {number} chunkSize 分片大小（默认 30KB，单位：字节）
	 * @returns {Array} 分割后的分片数组，每个元素包含分片信息
	 */
	static splitBase64IntoChunks = (base64Str : any, chunkSize = 30720) => {
		if (!base64Str || typeof base64Str !== 'string') {
			console.error('无效的 Base64 字符串');
			return [];
		}

		// 步骤1：移除 Base64 前缀（如 "data:image/png;base64,"）
		const pureBase64 = base64Str.replace(/^data:image\/\w+;base64,/, '');

		// 步骤2：计算 30KB 对应的 Base64 字符数
		// 原理：Base64 编码后体积是原二进制的 4/3，因此 30KB 二进制对应的 Base64 字符数 = 30720 * 4 / 3 = 40960
		const base64ChunkLength = Math.ceil(chunkSize * 4 / 3);

		// 步骤3：分割 Base64 为数组
		const chunks = [];
		const totalLength = pureBase64.length;
		let currentIndex = 0;

		while (currentIndex < totalLength) {
			// 计算当前分片的结束索引（不超过总长度）
			const endIndex = Math.min(currentIndex + base64ChunkLength, totalLength);
			// 截取分片数据
			const chunkData = pureBase64.substring(currentIndex, endIndex);

			chunks.push({
				chunkIndex: chunks.length, // 分片索引（从0开始）
				data: chunkData, // 分片的 Base64 数据（纯数据，无前缀）
				size: chunkData.length, // 分片大小（字符数）
				binarySize: Math.floor(chunkData.length * 3 / 4) // 对应二进制大小（字节）
			});

			currentIndex = endIndex;
		}

		return chunks;
	}
	// 判断是否请求成功
	static isReqOk(res : any) {
		if (res?.Result?.ResponseStatus?.IsSuccess) {
			return true
		}
		Utils.showErr(res.Result.ResponseStatus.Errors[0].Message);
		return false;

	}
	// 通过分类编码获取辅助资料列表
	static getAssistantInfo = async (FNumber = 'RKDJFFS') => {
		const res : any = await getOrderList({
			data: JSON.stringify({
				FormId: Utils.getFormId('辅助资料'),
				FieldKeys: "FNumber,FDataValue,FId.FNumber",
				FilterString: [
					Utils.getFilterString('FId.FNumber', FNumber, '=', '', ''),
					Utils.getFilterString('FDocumentStatus', 'C', '105', '', ''),
					Utils.getFilterString('FForbidStatus', 'A', '105', '', ''),
				],
				OrderString: '',
				assistantList: []
			}),
		})

		const list = res.map((v : any) => {
			return {
				name: v[1],
				FNumber: v[0],
				FName: v[1]
			}
		});
		return list || []
	}
}